﻿using Drive.LiveChat.Server;
using Drive.LiveChat.Server.Controllers;
using Drive.LiveChat.Server.Models;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;

namespace Drive.LiveExcelHost.Services
{
    /// <summary>
    /// 访客端消息收发
    /// </summary>
    public class VisitorMessenger : SocketIOService
    {
        VisitorChatController controller = new VisitorChatController();

        public VisitorMessenger(Request request, WebSocketSession session) : base(request, session)
        {
        }

        public override async Task OnMessageReceived(string type, string content)
        {
            var d = JSON.Parse<VisitorMessage>(content);
            if (session.IsSendTooFrenquncy())
            {
                this.session.PushToClient(session.SessionId, TypedMessage.CreateThrottle("[手速太快已屏蔽]"));
            }
            else
            {
                var visitorId = this.session.VisitorId;
                LiveChat.Model.ChatMessage m = null;
                var conv = controller.HandleVisitorMessage(visitorId, 0, false, d.Content, out m);
                var redisChannel = "agent_" + conv.AgentId;
                //visitor send message on browser
                //server received message
                //server transfer message to agent.

                var dpush = TypedMessage.CreateMessageFromVisitor(this.session.GetBuddy(), m, conv);
                await RedisPubSub.Publish(redisChannel, dpush);

                this.session.PushToClient(this.session.RedisChannel, TypedMessage.CreateChatPersist(d.Id, m.Id));
            }
        }

        internal async override Task OnSocketIoSessionCreate()
        {
            await RedisPubSub.Subscribe(this.session.RedisChannel, this.session.PushToClient); //私信
            var sessionCount = RedisWebSocketSession.Increase(this.session.RedisChannel);

            RedisVisitorStatus.SetStatusOnline(this.session.VisitorId, true);

            var sessionReady = TypedMessage.CreateSessionReady(session.GetBuddy(), new
            {
                sessionCount = sessionCount
            });
            this.session.PushToClient(this.session.SessionId, sessionReady);
            SendChatHistory();
        }

        private void SendChatHistory()
        {
            int page = 1;
            int size = 20;
            var messages = controller.GetMessages(this.session.VisitorId, 0, page, size);
            var json = TypedMessage.CreateHistory(messages);
            session.PushToClient(this.session.SessionId, json);
        }

        internal async override Task OnSocketIoSessionDestory()
        {
            await RedisPubSub.Unsubscribe("None", this.session.PushToClient); //大厅消息
            await RedisPubSub.Unsubscribe(this.session.RedisChannel, this.session.PushToClient); //私信

            var sessionCount = RedisWebSocketSession.Decrease(this.session.RedisChannel);
            RedisVisitorStatus.SetStatusOnline(this.session.VisitorId, sessionCount > 0);
            if (sessionCount == 0)
            {
                await RedisPubSub.Publish("None", TypedMessage.CreateBuddyLeave(session.GetBuddy(), new { }));
            }
        }

        public override void Dispose()
        {
            this.controller.Dispose();
            base.Dispose();
        }
    }
}
